﻿package net.wangit.util;

import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/**
 * XML工具类
 * 
 * @author watson Feb 22, 2010
 */
public class XMLUtil {

	private static final Log log = LogFactory.getLog(XMLUtil.class);

	/**
	 * 解析资源文件名为fileName的xml文件
	 * 
	 * @param fileName
	 * @return
	 */
	public static Document parseByFileName(String fileName) {
		InputStream stream = null;
		try {
			Document document;
			stream = XMLUtil.class.getResourceAsStream((new StringBuilder("/"))
					.append(fileName).toString());
			SAXReader reader = new SAXReader();
			document = reader.read(stream);
			try {
				if (stream != null) {
					stream.close();
				}
			} catch (IOException ioe) {
				log.error("could not close stream", ioe);
			}
			return document;
		} catch (Exception e) {
			log.error(new StringBuilder("could not read XML : ").append(
					fileName).toString());
		} finally {
			try {
				if (stream != null) {
					stream.close();
				}
			} catch (IOException ioe) {
				log.error("could not close stream", ioe);
			}
		}
		return null;
	}

	/**
	 * 解析路径为path的xml文件
	 * 
	 * @param path
	 * @return
	 */
	public static Document parseByPath(String path) {
		InputStream stream;
		if (!FileUtil.exists(path)) {
			if (log.isDebugEnabled())
				log.warn(new StringBuilder("could not found XML : ").append(
						path).toString());
			return null;
		}
		stream = null;
		try {
			Document document;
			stream = new FileInputStream(path);
			SAXReader reader = new SAXReader();
			document = reader.read(stream);
			try {
				if (stream != null) {
					stream.close();
				}
			} catch (IOException ioe) {
				log.error("could not close stream", ioe);
			}
			return document;
		} catch (Exception e) {
			log.error(new StringBuilder("could not read XML : ").append(path)
					.toString());
			try {
				if (stream != null) {
					stream.close();
				}
			} catch (IOException ioe) {
				log.error("could not close stream", ioe);
			}
		}
		return null;
	}

	public static void write(Document document, String path) throws IOException {
		write(document, path, null);
	}

	public static void writeUTF8(Document document, String path)
			throws IOException {
		write(document, path, "UTF-8");
	}

	/**
	 * 按指定编码encoding将document保存路径为path的文件
	 * 
	 * @param document
	 * @param path
	 * @param encoding
	 * @throws IOException
	 */
	public static void write(Document document, String path, String encoding)
			throws IOException {
		path = FileUtil.formatPath(path);
		String dir = path.substring(0, path.lastIndexOf('/'));
		FileUtil.mkdirs(dir);
		OutputFormat format = OutputFormat.createPrettyPrint();
		if (!Checker.isEmpty(encoding))
			format.setEncoding(encoding);
		XMLWriter writer = new XMLWriter(new FileWriter(path), format);
		writer.write(document);
		writer.close();
	}

	public static String getTextString(Element parent, String elementName,
			String defaultValue) {
		String value = parent != null ? parent.elementText(elementName) : null;
		return value != null ? value : defaultValue;
	}

	public static int getTextInt(Element parent, String elementName,
			int defaultValue) {
		String value = parent != null ? parent.elementText(elementName) : null;
		return Checker.isEmpty(value) ? defaultValue : Integer.parseInt(value);
	}

	public static long getTextLong(Element parent, String elementName,
			long defaultValue) {
		String value = parent != null ? parent.elementText(elementName) : null;
		return Checker.isEmpty(value) ? defaultValue : Long.parseLong(value);
	}

	public static boolean getTextBoolean(Element parent, String elementName,
			boolean defaultValue) {
		String value = parent != null ? parent.elementText(elementName) : null;
		return Checker.isEmpty(value) ? defaultValue : Boolean.valueOf(value)
				.booleanValue();
	}

	public static String getAttributeString(Element element, String attribute,
			String defaultValue) {
		String value = element != null ? element.attributeValue(attribute)
				: null;
		return Checker.isEmpty(value) ? defaultValue : value;
	}

	/**
	 * parent下存在节点名称为elementName的则更新该节点文本，不存在则新增
	 * 
	 * @param parent
	 * @param elementName
	 * @param value
	 */
	public static void setOrAddText(Element parent, String elementName,
			String value) {
		Element el = parent.element(elementName);
		if (el == null) {
			parent.addElement(elementName).setText(value);
		} else {
			el.setText(value);
		}
	}

	/**
	 * element内存在属性名称为attribute的则更新该属性值，不存在则新增
	 * 
	 * @param element
	 * @param attribute
	 * @param value
	 */
	public static void setOrAddAttribute(Element element, String attribute,
			String value) {
		Attribute attr = element.attribute("attribute");
		if (attr == null) {
			element.addAttribute(attribute, value);
		} else {
			attr.setValue(value);
		}
	}

	private XMLUtil() {
	}
}
